package utils

import (
	"fmt"
	"sync"
	"time"

	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

// TransferRecord 转发记录
type TransferRecord struct {
	ID         uint      `gorm:"primaryKey" json:"id"`
	Name       string    `gorm:"size:255;not null" json:"name"`
	LocalHost  string    `gorm:"size:255;not null" json:"local_host"`
	LocalPort  string    `gorm:"size:10;not null" json:"local_port"`
	TargetHost string    `gorm:"size:255;not null" json:"target_host"`
	TargetPort string    `gorm:"size:10;not null" json:"target_port"`
	Protocol   string    `gorm:"size:10;not null" json:"protocol"`
	CreatedAt  time.Time `json:"created_at"`
	UpdatedAt  time.Time `json:"updated_at"`
}

// NotepadRecord 记事本记录
type NotepadRecord struct {
	ID        uint      `gorm:"primaryKey" json:"id"`
	Name      string    `gorm:"size:255;not null" json:"name"`
	Content   string    `gorm:"type:text" json:"content"`
	FilePath  string    `gorm:"size:500" json:"file_path"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

// Database 数据库管理器
type Database struct {
	db    *gorm.DB
	mutex sync.RWMutex
}

var globalDB *Database
var dbOnce sync.Once

// GetDatabase 获取全局数据库实例
func GetDatabase() *Database {
	dbOnce.Do(func() {
		globalDB = &Database{}
		globalDB.init()
	})
	return globalDB
}

// init 初始化数据库
func (d *Database) init() {
	d.mutex.Lock()
	defer d.mutex.Unlock()

	var err error

	// 创建数据库连接
	d.db, err = gorm.Open(sqlite.Open("sokit.db"), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Silent), // 关闭GORM日志输出
	})
	if err != nil {
		GetLogger().Error("数据库连接失败: %v", err)
		return
	}

	// 自动迁移数据库结构
	err = d.db.AutoMigrate(&TransferRecord{}, &NotepadRecord{})
	if err != nil {
		GetLogger().Error("数据库迁移失败: %v", err)
		return
	}

	GetLogger().Info("数据库初始化成功")
}

// === 转发记录相关操作 ===

// SaveTransferRecord 保存转发记录
func (d *Database) SaveTransferRecord(record *TransferRecord) error {
	d.mutex.Lock()
	defer d.mutex.Unlock()

	if d.db == nil {
		return fmt.Errorf("数据库未初始化")
	}

	result := d.db.Create(record)
	if result.Error != nil {
		GetLogger().Error("保存转发记录失败: %v", result.Error)
		return result.Error
	}

	GetLogger().Info("保存转发记录成功: %s", record.Name)
	return nil
}

// GetTransferRecords 获取所有转发记录
func (d *Database) GetTransferRecords() ([]TransferRecord, error) {
	d.mutex.RLock()
	defer d.mutex.RUnlock()

	if d.db == nil {
		return nil, fmt.Errorf("数据库未初始化")
	}

	var records []TransferRecord
	result := d.db.Order("created_at desc").Find(&records)
	if result.Error != nil {
		GetLogger().Error("获取转发记录失败: %v", result.Error)
		return nil, result.Error
	}

	return records, nil
}

// GetTransferRecordByID 根据ID获取转发记录
func (d *Database) GetTransferRecordByID(id uint) (*TransferRecord, error) {
	d.mutex.RLock()
	defer d.mutex.RUnlock()

	if d.db == nil {
		return nil, fmt.Errorf("数据库未初始化")
	}

	var record TransferRecord
	result := d.db.First(&record, id)
	if result.Error != nil {
		return nil, result.Error
	}

	return &record, nil
}

// UpdateTransferRecord 更新转发记录
func (d *Database) UpdateTransferRecord(record *TransferRecord) error {
	d.mutex.Lock()
	defer d.mutex.Unlock()

	if d.db == nil {
		return fmt.Errorf("数据库未初始化")
	}

	result := d.db.Save(record)
	if result.Error != nil {
		GetLogger().Error("更新转发记录失败: %v", result.Error)
		return result.Error
	}

	GetLogger().Info("更新转发记录成功: %s", record.Name)
	return nil
}

// DeleteTransferRecord 删除转发记录
func (d *Database) DeleteTransferRecord(id uint) error {
	d.mutex.Lock()
	defer d.mutex.Unlock()

	if d.db == nil {
		return fmt.Errorf("数据库未初始化")
	}

	result := d.db.Delete(&TransferRecord{}, id)
	if result.Error != nil {
		GetLogger().Error("删除转发记录失败: %v", result.Error)
		return result.Error
	}

	GetLogger().Info("删除转发记录成功: ID=%d", id)
	return nil
}

// === 记事本记录相关操作 ===

// SaveNotepadRecord 保存记事本记录
func (d *Database) SaveNotepadRecord(record *NotepadRecord) error {
	d.mutex.Lock()
	defer d.mutex.Unlock()

	if d.db == nil {
		return fmt.Errorf("数据库未初始化")
	}

	result := d.db.Create(record)
	if result.Error != nil {
		GetLogger().Error("保存记事本记录失败: %v", result.Error)
		return result.Error
	}

	GetLogger().Info("保存记事本记录成功: %s", record.Name)
	return nil
}

// GetNotepadRecords 获取所有记事本记录
func (d *Database) GetNotepadRecords() ([]NotepadRecord, error) {
	d.mutex.RLock()
	defer d.mutex.RUnlock()

	if d.db == nil {
		return nil, fmt.Errorf("数据库未初始化")
	}

	var records []NotepadRecord
	result := d.db.Order("updated_at desc").Find(&records)
	if result.Error != nil {
		GetLogger().Error("获取记事本记录失败: %v", result.Error)
		return nil, result.Error
	}

	return records, nil
}

// GetNotepadRecordByID 根据ID获取记事本记录
func (d *Database) GetNotepadRecordByID(id uint) (*NotepadRecord, error) {
	d.mutex.RLock()
	defer d.mutex.RUnlock()

	if d.db == nil {
		return nil, fmt.Errorf("数据库未初始化")
	}

	var record NotepadRecord
	result := d.db.First(&record, id)
	if result.Error != nil {
		return nil, result.Error
	}

	return &record, nil
}

// UpdateNotepadRecord 更新记事本记录
func (d *Database) UpdateNotepadRecord(record *NotepadRecord) error {
	d.mutex.Lock()
	defer d.mutex.Unlock()

	if d.db == nil {
		return fmt.Errorf("数据库未初始化")
	}

	result := d.db.Save(record)
	if result.Error != nil {
		GetLogger().Error("更新记事本记录失败: %v", result.Error)
		return result.Error
	}

	GetLogger().Info("更新记事本记录成功: %s", record.Name)
	return nil
}

// DeleteNotepadRecord 删除记事本记录
func (d *Database) DeleteNotepadRecord(id uint) error {
	d.mutex.Lock()
	defer d.mutex.Unlock()

	if d.db == nil {
		return fmt.Errorf("数据库未初始化")
	}

	result := d.db.Delete(&NotepadRecord{}, id)
	if result.Error != nil {
		GetLogger().Error("删除记事本记录失败: %v", result.Error)
		return result.Error
	}

	GetLogger().Info("删除记事本记录成功: ID=%d", id)
	return nil
}

// === 通用操作 ===

// Close 关闭数据库连接
func (d *Database) Close() error {
	d.mutex.Lock()
	defer d.mutex.Unlock()

	if d.db == nil {
		return nil
	}

	sqlDB, err := d.db.DB()
	if err != nil {
		return err
	}

	return sqlDB.Close()
}

// GetDB 获取数据库连接（用于复杂查询）
func (d *Database) GetDB() *gorm.DB {
	d.mutex.RLock()
	defer d.mutex.RUnlock()
	return d.db
}

// CleanupOldRecords 清理旧记录（保留最近30天的记录）
func (d *Database) CleanupOldRecords() error {
	d.mutex.Lock()
	defer d.mutex.Unlock()

	if d.db == nil {
		return fmt.Errorf("数据库未初始化")
	}

	// 清理30天前的转发记录
	thirtyDaysAgo := time.Now().AddDate(0, 0, -30)

	result := d.db.Where("created_at < ?", thirtyDaysAgo).Delete(&TransferRecord{})
	if result.Error != nil {
		GetLogger().Error("清理旧转发记录失败: %v", result.Error)
		return result.Error
	}

	if result.RowsAffected > 0 {
		GetLogger().Info("清理了 %d 条旧转发记录", result.RowsAffected)
	}

	// 清理30天前的记事本记录
	result = d.db.Where("updated_at < ?", thirtyDaysAgo).Delete(&NotepadRecord{})
	if result.Error != nil {
		GetLogger().Error("清理旧记事本记录失败: %v", result.Error)
		return result.Error
	}

	if result.RowsAffected > 0 {
		GetLogger().Info("清理了 %d 条旧记事本记录", result.RowsAffected)
	}

	return nil
}
